//
//  GUIlayer.cpp
//  AtmKiller
//
//  Created by USoft on 6/10/14.
//
//

#include "GUIlayer.h"

GUILayer::GUILayer() {
    this->gameModel = GameModel::getInstance();
    this->initialize();
    this->notiBoards = __Array::create();
    CC_SAFE_RETAIN(this->notiBoards);
}

GUILayer::~GUILayer() {
    Utils::safeRelease(this->currentCountScoreDouble);
    
}

void GUILayer::onEnter() {
    Layer::onEnter();
}

void GUILayer::onExit() {
    Layer::onExit();
    this->removeAllChildrenWithCleanup(true);
}

void GUILayer::update(float dt) {
    GameModel* gameModel = GameModel::getInstance();
    BigNumber* score = gameModel->getScore();
    this->updateCurrentScore(score);
    //update total speed
    char totalSpeedStr[200];
    char* totalSpeedDisplay = gameModel->getCounter()->getTotalSpeed()->display();
    sprintf(totalSpeedStr, TXT_SPEED_AUTO_CHARACTER, totalSpeedDisplay);
    delete []totalSpeedDisplay;
    this->speedLabel->setString(totalSpeedStr);
    // update x combo
    char xCombo[10];
    sprintf(xCombo, "x%d", gameModel->getCombo()->getCurrentComboInt());
    this->currentComboLabel->setString(xCombo);
    // update combo bar
    float currentCombo = gameModel->getCombo()->getCurrentCombo();
    this->comboBar->setValue(currentCombo - floor(currentCombo));
    // update notification
    {
        Face* notiFace = (Face*)this->characterButton->getChildByTag(0);
        Label* numberNotiLabel = (Label*)notiFace->getChildByTag(0);
        if (this->gameModel->getNumberOfNoti() > 0) {
            notiFace->setVisible(true);
            char newNumberNoti[5];
            sprintf(newNumberNoti, "%d", this->gameModel->getNumberOfNoti());
            numberNotiLabel->setString(newNumberNoti);
        } else {
            notiFace->setVisible(false);
        }
    }
    // update character button
    if (gameModel->getGameState() == GS_UPGRADE) {
        this->characterButton->setEnabled(false);
        this->pauseButton->setEnabled(false);
//        this->shoppingButton->setEnabled(false);
    } else if (gameModel->getGameState() == GS_PLAY) {
        this->characterButton->setEnabled(true);
        this->pauseButton->setEnabled(true);
//        this->shoppingButton->setEnabled(true);
    } else if (gameModel->getGameState() == GS_ACHIEVEMENT) {
        this->characterButton->setEnabled(false);
        this->pauseButton->setEnabled(false);
//        this->shoppingButton->setEnabled(false);
    } else if (gameModel->getGameState() == GS_PAUSE){
        this->pauseButton->setEnabled(false);
        this->characterButton->setEnabled(false);
//        this->shoppingButton->setEnabled(false);
    } else if (gameModel->getGameState() == GS_CHARACTER) {
        this->pauseButton->setEnabled(false);
        this->characterButton->setEnabled(false);
//        this->shoppingButton->setEnabled(false);
    } else if (gameModel->getGameState() == GS_SHOPPING) {
        this->pauseButton->setEnabled(false);
        this->characterButton->setEnabled(false);
//        this->shoppingButton->setEnabled(false);
    }
}

void GUILayer::initialize() {
    this->guiListener = GUIListener::create();
    this->guiListener->setHandlerObj(this);
    this->guiListener->setShowAchievementNoti(ug_listener_func(GUILayer::onShowAchievementNoti));
    this->gameModel->addListener(this->guiListener);
    
    
    this->headerLayer = 0;
    //create currentCountScoreDouble tu luu score de so sanh voi score cua gameModel
    this->currentCountScoreDouble = BigNumber::create();
    this->currentCountScoreDouble->initialize(0);
    CC_SAFE_RETAIN(this->currentCountScoreDouble);
    
    this->createLayers();
    this->createLayersContent();
}

void GUILayer::createLayers() {
    //currentScoreFace layer & headerLayer
    this->headerLayer = UGLayer::create();
    this->addChild(this->headerLayer);
    this->headerLayer->setPosition(Point::ZERO);
    
    this->notiLayer = UGLayer::create();
    this->addChild(this->notiLayer);
    this->headerLayer->setPosition(Point::ZERO);
}

void GUILayer::createLayersContent() {
    GameModel* gameModel = GameModel::getInstance();
    Size gameSize = gameModel->getDisplayResolutionSize();
    
    //scoreBoard Face
    this->scoreBoard = new Face();
    this->scoreBoard->initWithFile(ANI_BOARD_SCORE_BOARD);
    this->scoreBoard->setPosition(gameSize.width/2, gameSize.height - this->scoreBoard->getContentSize().height/2 + 5);
    this->addChild(this->scoreBoard);
    
    //current score label
    Label* dollarSignLabel = Utils::createLabel((char*)"$", (char*)FONT_TRANSFORMER, 40);
    dollarSignLabel->setPosition(160,37);
    this->scoreBoard->addChild(dollarSignLabel);
    
    this->currentScoreLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 40);
    this->currentScoreLabel->setPosition(this->scoreBoard->getContentSize().width/2, this->scoreBoard->getContentSize().height/2 - 25);
    this->currentScoreLabel->setDimensions(800, this->currentScoreLabel->getContentSize().height);
    this->scoreBoard->addChild(this->currentScoreLabel);
    
    //speed Label
    this->speedLabel = Utils::createLabel((char*) "abc",(char*)FONT_TRANSFORMER, 28);
    this->speedLabel->setColor(Color3B(128, 215, 255));
    this->speedLabel->setDimensions(designResolutionSize.width, 0);
    this->speedLabel->setPosition(this->scoreBoard->getContentSize().width/2 - 30, this->scoreBoard->getContentSize().height/2 + 30);
    this->scoreBoard->addChild(this->speedLabel);
    
    //comboBar
    this->comboBar = StatusBar::create();
    this->comboBar->initWithParameter((char*) ANI_BOARD_SCORE_COMBO, (char*)ANI_BOARD_COMBO_BAR);
    this->comboBar->setPosition(this->speedLabel->getPositionX() + 275,this->speedLabel->getPositionY() + 3);
    
    this->scoreBoard->addChild(this->comboBar);
    Size comboBarSize = this->comboBar->getContentSize();
    
    //current x combo
    this->currentComboLabel = Utils::createLabel((char*)"0", (char*)FONT_TRANSFORMER, 28);
    this->currentComboLabel->setPosition(this->comboBar->getPositionX() + 80, this->comboBar->getPositionY());
    this->currentComboLabel->setColor(Color3B(128,215,255));
    this->scoreBoard->addChild(this->currentComboLabel);
    //buttons
    UGMenu* headerMenu = UGMenu::create();
    headerMenu->setPosition(Point::ZERO);
    this->addChild(headerMenu);
    {
        this->characterButton = Utils::createButton((char*) ANI_BUTTON_CHARACTER_1, (char*) ANI_BUTTON_CHARACTER_2);
        Size characterButtonSize = this->characterButton->getContentSize();
        float characterButtonX = gameSize.width/2 + this->scoreBoard->getContentSize().width/2 + this->characterButton->getContentSize().width/2 + 10;
        float characterButtonY = gameSize.height - characterButtonSize.height/2-5;
        this->characterButton->setPosition(Point(characterButtonX, characterButtonY));
        
        Face* notiFace = new Face();
        notiFace->initWithSpriteFrameName(ANI_NOTI_2);
        notiFace->setPosition(this->characterButton->getContentSize().width - notiFace->getContentSize().width/2 + 12, this->characterButton->getContentSize().height - 12);
        notiFace->setTag(0);
        this->characterButton->addChild(notiFace);
        
        Label* numberNotiLabel = Utils::createLabel((char*)"0", (char*)FONT_MYRIADPRO_BOLD, 18);
        numberNotiLabel->setPosition(notiFace->getContentSize().width/2, notiFace->getContentSize().height/2 - 3);
        numberNotiLabel->setDimensions(notiFace->getContentSize().width, numberNotiLabel->getContentSize().height);
        numberNotiLabel->setTag(0);
        notiFace->addChild(numberNotiLabel);
        
        headerMenu->addChild(this->characterButton);
    }
    {
        this->pauseButton = Utils::createButton((char*) ANI_BUTTON_PAUSE_1, (char*)ANI_BUTTON_PAUSE_2);
        Size pauseButtonSize = this->pauseButton->getContentSize();
        float pauseButtonX = gameSize.width/2 - this->scoreBoard->getContentSize().width/2 - this->pauseButton->getContentSize().width/2 - 10;
        float pauseButtonY = gameSize.height - pauseButtonSize.height/2 - 5;
        this->pauseButton->setPosition(Point(pauseButtonX, pauseButtonY));
        headerMenu->addChild(this->pauseButton);
    }
    {
    }
}

void GUILayer::createAchievementNoti(int achievementId) {
    Face* notiBoard = new Face();
    notiBoard->initWithSpriteFrameName(ANI_NOTI_BOARD);
    this->notiLayer->addChild(notiBoard);
    Size gameSize = this->gameModel->getDisplayResolutionSize();
    notiBoard->setPosition(gameSize.width/2, this->scoreBoard->getPositionY() - this->scoreBoard->getContentSize().height/2 - 10 - notiBoard->getContentSize().height/2);
    this->notiBoards->addObject(notiBoard);
    
    AbstractAchievement* achievement = (AbstractAchievement*) this->gameModel->getAchievements()->getObjectAtIndex(achievementId);
    //notiLabel
    Label* titleNotiLabel = Utils::createLabel((char*)"Achievement Unlocked", (char*)FONT_TRANSFORMER, 21);
    titleNotiLabel->setColor(Color3B(255,0,0));
    titleNotiLabel->setAnchorPoint(Point(0,1));
    titleNotiLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    titleNotiLabel->setPosition(25,95);
    notiBoard->addChild(titleNotiLabel);
    titleNotiLabel->setTag(0);
    //notiName
    char name[100];
    sprintf(name, "%s", achievement->getName().c_str());
    Label* nameLabel = Utils::createLabel(name, (char*)FONT_TRANSFORMER, 25);
    nameLabel->setColor(Color3B(128,215,255));
    nameLabel->setAnchorPoint((Point(0,1)));
    nameLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    nameLabel->setDimensions(notiBoard->getContentSize().width - 35, nameLabel->getContentSize().height);
    nameLabel->setPosition(25, titleNotiLabel->getPositionY() - 22);
    notiBoard->addChild(nameLabel);
    nameLabel->setTag(1);
    //notiDesc
    char description[100];
    sprintf(description, "%s", achievement->getDescription().c_str());
    Label* desLabel = Utils::createLabel(description, (char*)FONT_MYRIADPRO_REGULAR, 15);
    desLabel->setColor(Color3B(255,255,255));
    desLabel->setAnchorPoint((Point(0,1)));
    desLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    desLabel->setPosition(25, nameLabel->getPositionY() - 22);
    desLabel->setDimensions(notiBoard->getContentSize().width - 35, 100);
    notiBoard->addChild(desLabel);
    desLabel->setTag(2);
    //notiEffect
    char effect[100];
    if (achievement->getEffectType() == ACHIEVEMENT_EFFECT_DPS){
        sprintf(effect, "Effect: Increase %.2f %% MPS of all characters", achievement->getEffectPercent() * 100);
    } else if (achievement->getEffectType() == ACHIEVEMENT_EFFECT_GRANDMA){
        sprintf(effect, "Effect: Increase %.2f %% MPS of Grandma", achievement->getEffectPercent() * 100);
    } else if (achievement->getEffectType() == ACHIEVEMENT_EFFECT_GAMEDEV){
        sprintf(effect, "Effect: Increase %.2f %% MPS of Game developer", achievement->getEffectPercent() * 100);
    }
    Label* effectLabel = Utils::createLabel(effect, (char*)FONT_MYRIADPRO_REGULAR, 15);
    effectLabel->setColor(Color3B(255,255,255));
    effectLabel->setAnchorPoint((Point(0,1)));
    effectLabel->setHorizontalAlignment(TextHAlignment::LEFT);
    effectLabel->setPosition(25, desLabel->getPositionY() - 18);
    effectLabel->setDimensions(notiBoard->getContentSize().width - 35, 100);
    notiBoard->addChild(effectLabel);
    effectLabel->setTag(2);
    
    //close button
    UGMenu* closeMenu = UGMenu::create();
    closeMenu->setPosition(Point::ZERO);
    notiBoard->addChild(closeMenu);
    
    MenuItemSprite* closeButton = Utils::createButton((char*)ANI_BUTTON_CLOSE_1, (char*)ANI_BUTTON_CLOSE_2);
    closeButton->setPosition(notiBoard->getContentSize().width + closeButton->getContentSize().width/2 - 20, notiBoard->getContentSize().height - closeButton->getContentSize().height/2);
    closeMenu->addChild(closeButton);
    closeButton->setCallback(CC_CALLBACK_1(GUILayer::onCloseNotification, this));
    closeButton->setTag(3);
}

void GUILayer::onShowAchievementNoti(Ref* data) {
    __Integer* idInteger = (__Integer*)data;
    this->createAchievementNoti(idInteger->getValue());
}

void GUILayer::onCloseNotification(Ref *sender) {
    Face* notiBoard = (Face*)this->notiBoards->getLastObject();
    notiBoard->removeAllChildrenWithCleanup(true);
    notiBoard->removeFromParentAndCleanup(true);
    this->notiBoards->removeLastObject();
}

void GUILayer::updateCurrentScore(BigNumber* score) {
    if (this->currentCountScoreDouble->compare(score)==0) {
        return;
    }
    //update CurrentScore
    auto delCurrentScore = this->currentCountScoreDouble;
    this->currentCountScoreDouble = BigNumber::create(); //GUI Layer Class cung tu luu 1 score va so sanh voi gameModel->getScore()
    char scoreText[100];
    char* scoreString = score->display();
    sprintf(scoreText, "%s", scoreString);
    this->currentCountScoreDouble->initialize(scoreString);
    CC_SAFE_RETAIN(this->currentCountScoreDouble);
    this->currentScoreLabel->setString(scoreText);
    Utils::safeRelease(delCurrentScore);
    delete[] scoreString;
}
